package cn.juque.common.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.juque.common.constants.BaseOrderEnum;
import cn.juque.common.constants.MessageEnum;
import cn.juque.common.constants.StringConstants;
import cn.juque.common.exception.AppException;

import java.util.LinkedHashMap;
import java.util.List;

/**
 * @author nuoka
 * @version 1.0.0
 * <li>IntelliJ IDEA</li>
 * <li>cn.juque.cn.juque.common.utils</li>
 * @date 2020/5/12 0:02
 **/
public class OrderByUtil {

  private static final String DESC = "DESC";
  private static final String ASC = "ASC";

  private OrderByUtil() {}

  /**
   *<li>排序规则约定： PRODUCT_ID_DESC, (PRODUCT_ID标识枚举名称，DESC为排序关键字)</li>
   * <li>枚举定义统一属性为field</li>
   * <li>允许排序的字段必须提前定义为枚举 {@link <code>cn.juque.fitnessmarket.constants.ComProductOrderByEnum</code>}</li>
   * <li>mybatis统一使用foreach解析BaseEntity的orderBy属性{@link <code>cn.juque.fitnessmarket.mapper.ComProductMapper.xml</code>}</li>
   * @param rules 排序规则
   * @return LinkedHashMap
   */
  public static <E extends Enum<E>> LinkedHashMap<String, String> cover(Class<E> enumClass, List<String> rules) {
    if (ObjectUtil.isNull(enumClass) || CollUtil.isEmpty(rules)) {
      return null;
    }
    LinkedHashMap<String, String> map  = new LinkedHashMap<>(rules.size());
    LinkedHashMap<String, E> enumMap = EnumUtil.getEnumMap(enumClass);
    String enumName;
    String order;
    BaseOrderEnum baseOrderEnum;
    for (String rule : rules) {
      enumName = CharSequenceUtil.subBefore(rule, StringConstants.UNDER_LINE, Boolean.TRUE);
      order = CharSequenceUtil.subAfter(rule, StringConstants.UNDER_LINE, Boolean.TRUE);
      if (CharSequenceUtil.isBlank(enumName) || CharSequenceUtil.isBlank(order)) {
        throw new AppException(MessageEnum.SYSTEM_FAIL.getCode(), "排序规则["+ rule +"]非法");
      }
      if (!enumMap.containsKey(enumName)) {
        throw new AppException(MessageEnum.SYSTEM_FAIL.getCode(), "排序规则["+ rule +"]未定义");
      }
      if (!CharSequenceUtil.equals(ASC, order, Boolean.TRUE) && !CharSequenceUtil.equals(DESC, order, Boolean.TRUE)) {
        throw new AppException(MessageEnum.SYSTEM_FAIL.getCode(), "排序规则["+ rule + "]非法");
      }
      baseOrderEnum = (BaseOrderEnum) enumMap.get(enumName);
      map.put(baseOrderEnum.getField(), order);
    }
    return map;
  }
}
